/*
 * Copyright:  (C) 2014 EAST
 *                  All rights reserved.
 *   Version:  1.0.0(07/30/2014)
 *    Author:  fulinux <fulinux@sina.com>
 * ChangeLog:  1, Release initial version on "07/30/2014 01:52:51 PM"
 *                 
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>
#include <net/if.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <linux/can/error.h>
#include <canbus.h>

/*
 * 测试过虑功能, 包括PGN过滤和CANID过滤
 */
int main (int argc, char **argv)
{
    int i, j;
    struct timeval timeout;
    struct can_filter filter[3];
    struct pgn_filter pfilter[2];
    can_eframe_t *can;

    can = can_init ("vcan0", 6, 0, 0xF4, 0xE5);
    if(NULL == can){
        perror("CAN INIT");
        return -1;
    }

    if(-1 == can_setdebug(can, TRUE)){
        perror("SET DEBUG");
        return -1;
    }

    /* 
     * 过滤标准帧中PF值等于0x01、0x03和0x04的帧. 
     * 在某些应用中pf中的值向左移动8bit时的值就
     * 是PGN的值. 综合标准帧和扩展帧的过滤规则
     * 知: PGN值等于768的帧都可以被过滤.
     */
    filter[0].can_id = (CAN_EFF_FLAG | (256 << 16));
    filter[0].can_mask = CAN_EFF_FLAG | 0xFF0000;
    filter[1].can_id = (CAN_EFF_FLAG | (768 << 16));
    filter[1].can_mask = CAN_EFF_FLAG | 0xFF0000;

    /* 
     * 过滤扩展帧时需要首先过滤扩展帧的标志,
     * 下面过滤扩展帧中PGN值等于512和768的帧. 
     */
    pfilter[0].pgn = 512;
    pfilter[0].mask = 0xFF00;
    pfilter[1].pgn = 1024;
    pfilter[1].mask = 0xFF00;
    if(-1 == can_setfilter(can, filter, sizeof(filter), pfilter, sizeof(pfilter))){
        perror("SET FILTER");
        return -1;
    }

    for(;;){
        timeout.tv_sec = 5;
        timeout.tv_usec = 0;
        if(can_recv(can, &timeout) == -1){
            perror("CAN RECV");
        }else{
            printf ("\n");
            printf ("pgn = %d\n", can->pgn);
            for(i = 0, j = 0; i < can->len; i++, j++){
                if(j > 7){
                    j = 0;
                    printf ("\n");
                }
                printf ("[%03d]", can->msg[i]);
            }
            printf ("\n");
            printf ("\n");
        }
    }

    if(-1 == can_exit(can)){
        perror("CAN EXIT");
        exit(-1);
    }

    return 0;
} /* ----- End of main() ----- */
